package com.vf.admin.client.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.vf.admin.client.common.ClientConstants;
import com.vf.admin.client.common.RedisKeys;
import com.vf.admin.client.dao.AppFamilyDao;
import com.vf.admin.client.dao.AppFamilyMemberDao;
import com.vf.admin.client.dto.RoomMemberDto;
import com.vf.admin.client.service.*;
import com.vf.admin.client.tx.utils.TxIm;
import com.vf.admin.client.tx.vo.RoomGiftVo;
import com.vf.admin.client.tx.vo.userSignVo;
import com.vf.admin.common.BaseController;
import com.vf.admin.common.Constants;
import com.vf.admin.common.entity.Result;
import com.vf.admin.common.redis.RedisUtil;
import com.vf.admin.common.splitpage.SplitPageBean;
import com.vf.admin.miaodong.entity.*;
import com.vf.admin.utils.StringEx;
import net.sf.json.JSONArray;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.*;

import static com.vf.admin.client.common.ClientConstants.client_toke;
import static com.vf.admin.client.tx.utils.TLSSigAPIv2.genUserSig;
import static com.vf.admin.client.tx.utils.TxIm.*;
import static com.vf.admin.client.tx.utils.txConfig.SDKAPPID;
import static com.vf.admin.common.Constants.*;
import static com.vf.admin.utils.StringEx.isNull;

/**
 * @author anxiang
 * @version 1.0.0
 * @ClassName AppDongtaiController.java
 * @Description 腾讯相关接口
 * @createTime 2021年07月21日 10:58:0
 */
@CrossOrigin
@Controller
@RequestMapping("/app/tx")
public class AppTxController extends BaseController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    AppUserService appUserService;
    @Autowired
    AppTxService appTxService;
    @Autowired
    AppRoomAdminService appRoomAdminService;
    @Autowired
    AppFansClubService appFansClubService;
    @Autowired
    AppRoomMeiliService appRoomMeiliService;
    @Autowired
    AppUserDressupService appUserDressupService;
    @Autowired
    AppTaskRecordService appTaskRecordService;
    @Autowired
    AppMingXiZuanShiService appMingXiZuanShiService;
    @Autowired
    AppSmsRecordService appSmsRecordService;
    @Autowired
    AppSetupService appSetupService;
    @Autowired
    AppRoomService appRoomService;
    @Autowired
    SystemAlertService systemAlertService;
    @Autowired
    AppFamilyDao appFamilyDao;
    @Autowired
    AppFamilyMemberDao appFamilyMemberDao;

    /**
     * @return com.vf.admin.common.entity.Result
     * @author anxiang
     * @Description 获取UserSig
     */
    @RequestMapping(value = "/getUserSig", method = RequestMethod.POST)
    @ResponseBody
    public Result getUserSig(HttpServletRequest request) {
        try {
            Map<String, Object> map = new HashMap<>(16);
            Integer userId = (Integer) redisUtil.get(RedisKeys.userToken + request.getHeader(client_toke));
            AppSetup setup = appSetupService.get();

            if (userId != null) {

                AppUser user = appUserService.get(userId);
                String sig = genUserSig(user.getTengxuncode() + "", 3600 * 24 * 7);
                map.put("userSig", sig);
                map.put("gfqun", setup.getGftxcode());
                map.put("logincode", user.getTengxuncode());
                map.put("appid", TX_SDKAPPID);

            }
            return sucess(map);
        } catch (Exception e) {
            logger.error("获取UserSig异常:", e);
            return this.errorJSON("系统繁忙，请稍后重试");
        }
    }

    /**
     * 腾讯创建房间
     *
     * @return
     */
    @RequestMapping(value = "/tencentCreateRoom", method = RequestMethod.POST)
    @ResponseBody
    public Result tencentCreateRoom(HttpServletRequest request) {
        try {
            //获取最新数据
            Integer userId = (Integer) redisUtil.get(RedisKeys.userToken + request.getHeader(ClientConstants.client_toke));
            //获取当前登录用户的user对象
            AppUser user = appUserService.get(userId);
            if (user.getShipinstate() == 2) {
                return errorJSON("你还没通过视频认证,无法创建房间");
            }
            if (user.getStatus() == 2) {
                return errorJSON("你还没通过身份认证,无法创建房间");
            }
            AppRoom room = appRoomService.getUserId(user.getId());
            if (StringUtils.isEmpty(room)) {
                return errorJSON("房间不存在");
            }
            //调用房间创建
            boolean flag = appRoomService.txCreatRoom(user, room);
            if (flag) {
                return sucessJSON("创建房间成功");
            } else {
                return errorJSON("创建房间失败");
            }
        } catch (Exception e) {
            logger.error("创建房间异常:", e);
            return this.errorJSON("系统繁忙，请稍后重试");
        }

    }


    /**
     * 腾讯统一回调方法
     *
     * @return
     */
    @RequestMapping(value = "/imNotifyUrl", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> imNotifyUrl(HttpServletRequest request) {
        Map<String, Object> map = new HashMap<>(16);
        map.put("ActionStatus", "OK");
        map.put("ErrorInfo", "");
        map.put("ErrorCode", 0);
        try {
            //获取sdkAppid
            String sdkAppid = request.getParameter("SdkAppid");
            //校验是否合法
            if (sdkAppid.equals(SDKAPPID + "")) {
                //获取回调头
                String callbackCommand = request.getParameter("CallbackCommand");
                //获取请求数据
                BufferedReader resultContent = request.getReader();
                String reader = resultContent.readLine();
                JSONObject jsonObject = JSONObject.parseObject(reader);
                Map<String, Object> res = (Map<String, Object>) jsonObject;
                if (callbackCommand.equals(IMCALLBACKBEFORESENDMSG)) {
                    System.out.println("---------------------------单聊消息发送之前回调-------------------------");
                } else if (callbackCommand.equals(IMCALLBACKAFTERNEWMEMBERJOIN)) {
                    System.out.println("---------------------------新成员入群之后回调-------------------------");
                    //腾讯方的群组ID==>app的房间腾讯code
                    Object groupId = res.get("GroupId");
                    //腾讯方的请求的操作者ID ==>app的用户腾讯code
                    Object operatorAccount = res.get("Operator_Account");
                    //通过腾讯code获取用户信息
                    AppUser user = appUserService.getTengxuncodeByUser(Integer.valueOf(operatorAccount.toString()));
                    /*
                     * 变更在线状态
                     */
                    appUserService.onlineUpstate(user.getId(), 0);
                    /*
                     * 变更用户上一次所在房间的腾讯code
                     */
                    appUserService.lastroomtxcode(user.getId(), Integer.valueOf(groupId.toString()));

                    /*
                     * 重新设置资料
                     */
                    userSignVo vo = new userSignVo();
                    //获取用户在该房间的魅力值
                    AppRoom room = appRoomService.getTxCode(Integer.valueOf(groupId.toString()));
                    AppRoomMeili roomMeili = appRoomMeiliService.getMeili(user.getId(), room.getId());
                    //判断魅力值记录是否存在   true取魅力值  false取0
                    long meilizhi = StringUtils.isEmpty(roomMeili) ? 0 : roomMeili.getMeilizhi();
                    vo.setCharmNum(meilizhi);
                    //获取用户设置的默认头饰
                    AppUserDressup userDressup = appUserDressupService.getUserid(user.getId(), 2);
                    //判断用户是否设置默认头像   true取头饰地址  false取""
                    String headWear = StringUtils.isEmpty(userDressup) ? "" : userDressup.getGoodpic();
                    vo.setHeadWear(headWear);
                    //光晕   0开  1关
                    vo.setHeadHalo(0);
                    //贵族id
                    vo.setNobleid(user.getNobleid());
                    //实名认证状态  1已认证  2未认证
                    vo.setStatus(user.getStatus());
                    //调用腾讯方进行更新
                    appTxService.updateUserProfile(vo, user.getTengxuncode());
                    /*
                     * 新手任务操作
                     */
                    //获取官方群
                    AppSetup setup = appSetupService.get();
                    //不想等  条件成立
                    if (!setup.getGftxcode().equals(Integer.valueOf(groupId.toString()))) {
                        //添加进房间任务
                        AppTaskRecord taskRecord = appTaskRecordService.getByTaskId(user.getId(), Constants.guankan_task);
                        if (org.springframework.util.StringUtils.isEmpty(taskRecord)) {
                            //appTaskRecordService.addTaskRecord(user.getId(), Constants.guankan_task);
                        }
                    }
                } else if (callbackCommand.equals(IMCALLBACKAFTERMEMBEREXIT)) {
                    System.out.println("---------------------------群成员离开之后回调-------------------------");
                    //群组 ID
                    Object groupId = res.get("GroupId");
                    //请求的操作者 UserID
                    Object operatorAccount = res.get("Operator_Account");
                    //新入群成员 UserID 集合
                    Object exitMemberList = res.get("ExitMemberList");
                    AppUser user = appUserService.getTengxuncodeByUser(Integer.valueOf(operatorAccount.toString()));
                    //变更在线状态
                    appUserService.onlineUpstate(user.getId(), 1);
                } else if (callbackCommand.equals(IMSTATECHANGE)) {
                    System.out.println("---------------------------用户在线状态变更回调-------------------------");
                    //用户上下线的信息
                    Object Info = res.get("Info");
                    System.out.println(Info);
                    JSONObject jsonObject1 = JSON.parseObject(Info.toString());
                    //在线状态   Login 表示上线（TCP 建立），Logout 表示下线（TCP 断开），Disconnect 表示网络断开
                    String Action = jsonObject1.getString("Action");
                    String ToAccount = jsonObject1.getString("To_Account");
                    AppUser user = appUserService.getTengxuncodeByUser(Integer.valueOf(ToAccount));
                    System.out.println("状态变更人：" + ToAccount);
                    if ("Login".equals(Action)) {
                        System.out.println("状态变更：Login || 登陆");
                        //变更在线状态
                        appUserService.onlineUpstate(user.getId(), 1);
                        if (Constants.duanxianUserMap.containsKey(ToAccount)) {
                            //存在则消除
                            Constants.duanxianUserMap.remove(ToAccount);
                        }
                    } else if ("Logout".equals(Action)) {
                        System.out.println("状态变更：Logout || 下线");
                        //变更在线状态
                        appUserService.onlineUpstate(user.getId(), 2);
                        if (Constants.duanxianUserMap.containsKey(ToAccount)) {
                            //存在则消除
                            Constants.duanxianUserMap.remove(ToAccount);
                        }
                    } else if ("Disconnect".equals(Action)) {
                        System.out.println("状态变更：Disconnect || 断开");
                        Constants.duanxianUserMap.put(ToAccount, new Date());
                    }
                } else if (callbackCommand.equals(AFTERSENDMSG)) {
                    logger.info("---------------------------群成员发送消息后回调-------------------------");
                    logger.info(JSON.toJSONString(res));

                    Integer groupId = Integer.valueOf(String.valueOf(res.get("GroupId")));
                    String fromAccountStr = String.valueOf(res.get("From_Account"));
                    if (!fromAccountStr.equalsIgnoreCase("administrator")) {
                        Integer fromAccount = Integer.valueOf(String.valueOf(res.get("From_Account")));
                        AppFamily family = appFamilyDao.findByFamilyId(groupId);
                        if (family != null) {
                            AppUser tengxuncodeByUser = appUserService.getTengxuncodeByUser(fromAccount);
                            List<AppFamilyMember> memberList = appFamilyMemberDao.getAllFamilyMemberByFidExistUserId(groupId, tengxuncodeByUser.getId());
                            //发送群新消息通知
                            for (AppFamilyMember b : memberList) {
                                AppUser appUser = appUserService.get(b.getUserid());
                                systemAlertService.familyNEWS(appUser.getTengxuncode());
                            }
                        }
                    }
                } else if (callbackCommand.equals(CallbackAfterMsgWithDraw)) {
                    logger.info("---------------------------单聊消息撤回后回调-------------------------");
                    logger.info(JSON.toJSONString(res));
                    Integer fromAccount = Integer.valueOf(String.valueOf(res.get("From_Account")));
                    Integer toAccount = Integer.valueOf(String.valueOf(res.get("To_Account")));

                    TxIm.sendUserMsgqbtAlert(toAccount, fromAccount, "对方撤回了一条消息（对方撤回消息不影响收益）");
                }
            } else {
                map.put("ActionStatus", "OK");
                map.put("ErrorInfo", "验证失败");
                map.put("ErrorCode", 120002);
            }
            return map;
        } catch (Exception x) {
            map.put("ActionStatus", "OK");
            map.put("ErrorInfo", "发送次数已用光");
            map.put("ErrorCode", 120002);
            logger.error("腾讯回调异常:", x);
            return map;
        }

    }

    /**
     * 获取房间成员列表
     *
     * @param pageno 第几页
     * @return
     */
    @RequestMapping("/getAListOfRoomMembers")
    @ResponseBody
    public Result getAListOfRoomMembers(Integer pageno, Integer roomid, String likecha) {
        try {
            if (StringEx.isNull(pageno)) {
                return this.errorJSON("pageno不能为空!");
            }
            if (StringEx.isNull(roomid)) {
                return this.errorJSON("roomid不能为空!");
            }
            AppRoom room = appRoomService.getById(roomid);
            if (StringUtils.isEmpty(room)) {
                return this.errorJSON("房间不存在!");
            }
            List<String> toList = new ArrayList<>();
            String list = getGroupMemberInfo(room.getTengxuncode());
            if (isNull(list)) {
                return this.sucessPage(toList, -1);
            } else {
                JSONArray data = JSONArray.fromObject(list);
                String tengxuncode = "";
                for (int i = 0; i < data.size(); i++) {
                    net.sf.json.JSONObject jobj = (net.sf.json.JSONObject) data.get(i);
                    Object MemberAccount = jobj.get("Member_Account");
                    tengxuncode += "," + MemberAccount;
                }
                SplitPageBean splitPage = new SplitPageBean(pageno, 10);
                List<RoomMemberDto> list2 = appUserService.getBatchTengxuncodeByUser(tengxuncode.substring(1), likecha, splitPage);
                for (RoomMemberDto roomMemberDto : list2) {
                    if (room.getUserid().equals(roomMemberDto.getId())) {
                        //通过，房主
                        roomMemberDto.setRoomrole(room_role_fangzhu);
                    } else {
                        //不通过
                        //判断用户是否是房间管理员
                        AppRoomAdmin roomAdmin = appRoomAdminService.getRoom(room.getId(), roomMemberDto.getId());
                        if (StringUtils.isEmpty(roomAdmin)) {
                            //未查询到记录, 用户身份
                            roomMemberDto.setRoomrole(room_role_user);
                        } else {
                            //查询到记录, 管理员身份
                            roomMemberDto.setRoomrole(room_role_admin);
                        }
                    }
                    //获取粉丝团
                    AppFansClub fansClub = appFansClubService.getFensiTuan(roomMemberDto.getId(), room.getRoomcode());
                    if (StringUtils.isEmpty(fansClub)) {
                        //未查询到记录
                        roomMemberDto.setIsfensi(2);
                    } else {
                        //查询到记录
                        roomMemberDto.setIsfensi(1);
                    }
                }
                return this.sucessPage(list2, splitPage.getNextPageNo());
            }
        } catch (Exception r) {
            logger.error("获取房间成员列表异常:", r);
            return this.errorJSON("系统繁忙，请稍后重试");
        }
    }


    /**
     * 开闭麦克风更新腾讯资料字段
     *
     * @param roomid  房间id
     * @param leixing 开闭麦状态   0开    1关
     * @return
     */
    @RequestMapping("/updateTencentProfileField")
    @ResponseBody
    public Result updateTencentProfileField(Integer roomid, Integer leixing, HttpServletRequest request) {
        try {
            if (StringEx.isNull(leixing)) {
                return this.errorJSON("开闭麦类型不能为空!");
            }
            if (leixing > 1 || leixing < 0) {
                return this.errorJSON("开闭麦类型不支持!");
            }
            if (StringEx.isNull(roomid)) {
                return this.errorJSON("房间id不能为空!");
            }
            AppRoom room = appRoomService.getById(roomid);
            if (StringUtils.isEmpty(room)) {
                return this.errorJSON("房间不存在!");
            }
            Integer userId = (Integer) redisUtil.get(RedisKeys.userToken + request.getHeader(client_toke));
            //获取当前登录用户的user对象
            AppUser user = appUserService.get(userId);
            /*
               发送开闭麦消息
             */
            RoomGiftVo vo1 = new RoomGiftVo();
            vo1.setShouliUser(user.getTengxuncode());
            vo1.setHeadHalo(leixing);
            //发送群组消息
            appTxService.sendGroupMessage(21, vo1, room.getTengxuncode());
            /*
               重新设置资料
             */
            userSignVo vo = new userSignVo();
            //获取用户在该房间的魅力值
            AppRoomMeili roomMeili = appRoomMeiliService.getMeili(user.getId(), room.getId());
            if (StringUtils.isEmpty(roomMeili)) {
                //未查询到记录, 魅力值为0
                vo.setCharmNum(0);
            } else {
                //查询到记录, 魅力值为记录值
                vo.setCharmNum(roomMeili.getMeilizhi());
            }
            AppUserDressup userDressup = appUserDressupService.getUserid(user.getId(), 2);
            if (StringUtils.isEmpty(userDressup)) {
                //未查询到记录
                vo.setHeadWear("");
            } else {
                //查询到记录
                vo.setHeadWear(userDressup.getGoodpic());
            }
            vo.setHeadHalo(leixing);
            vo.setNobleid(user.getNobleid());
            vo.setStatus(user.getStatus());
            //更新用户资料
            boolean flag = appTxService.updateUserProfile(vo, user.getTengxuncode());
            if (flag) {
                return sucessJSON("更新成功");
            } else {
                return errorJSON("更新失败");
            }
        } catch (Exception r) {
            logger.error("获取房间成员列表异常:", r);
            return this.errorJSON("系统繁忙，请稍后重试");
        }
    }


    /**
     * 获取房间在线人数
     *
     * @param roomid 房间id
     * @return
     */
    @RequestMapping("/getOnlineNumberOfRoom")
    @ResponseBody
    public Result getOnlineNumberOfRoom(Integer roomid, HttpServletRequest request) {
        try {
            if (StringEx.isNull(roomid)) {
                return this.errorJSON("房间id不能为空!");
            }
            AppRoom room = appRoomService.getById(roomid);
            if (StringUtils.isEmpty(room)) {
                return this.errorJSON("房间不存在!");
            }
            Integer userId = (Integer) redisUtil.get(RedisKeys.userToken + request.getHeader(client_toke));
            //获取当前登录用户的user对象
            AppUser user = appUserService.get(userId);

            //先查询redis
            Map<Object, Object> map = redisUtil.hmget("RoomOnline");
            Map<Integer, Integer> onMap = new HashMap<>(16);
            for (Map.Entry<Object, Object> entry : map.entrySet()) {
                Object mapKey = entry.getKey();
                Object mapValue = entry.getValue();
                onMap.put(Integer.valueOf(mapKey.toString()), Integer.valueOf(mapValue.toString()));
            }
            int zaixian = 0;
            if (onMap.containsKey(room.getTengxuncode())) {
                zaixian = Integer.valueOf(onMap.get(room.getTengxuncode()).toString());
            }
            Map<String, Object> toMap = new HashMap<>(16);
            toMap.put("zaixian", zaixian);

            return sucessJSON(toMap, "更新成功");

        } catch (Exception r) {
            logger.error("获取房间在线人数异常:", r);
            return this.errorJSON("系统繁忙，请稍后重试");
        }
    }

    /**
     * 根据用户账号添加腾讯云账号
     */
    @RequestMapping("/addUser")
    public void addUser() {
        String userSig = genUserSig("admin", 3600 * 24 * 7);
        String url = "https://console.tim.qq.com/v4/im_open_login_svc/account_import?sdkappid=1400800054&identifier=admin&usersig=" + userSig + "&random=2706793671&contenttype=json";
        List<AppUser> userList = appUserService.findAllList();
        for (AppUser user : userList) {
            String userId = "" + user.getTengxuncode();
            String nick = user.getNick();
            String imgUrl = user.getPic();
            String reqdata = "{"
                    + "\"UserID\":\"" + userId + "\","
                    + "\"Nick\":\"" + nick + "\","
                    + "\"FaceUrl\":\"" + imgUrl + "\""
                    + "}";

            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);
            StringEntity params = new StringEntity(reqdata, "utf-8");
            params.setContentType("application/json");
            httpPost.setEntity(params);

            try {
                HttpResponse response = httpClient.execute(httpPost);
                String strResult = EntityUtils.toString(response.getEntity(), "utf-8");
                org.json.JSONObject jsonObject = new org.json.JSONObject(strResult);
                Integer code = (Integer) jsonObject.get("ErrorCode");
                if (code == 0) {
                    System.out.println("导入成功");
                } else {
                    System.out.println("导入失败");
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    /**
     * 根据用户账号添加腾讯云账号
     */
    @RequestMapping("/delUsers")
    public void delUsers() {
        String userSig = genUserSig("admin", 3600 * 24 * 7);
        String url = "https://console.tim.qq.com/v4/im_open_login_svc/account_delete?sdkappid=1400800054&identifier=admin&usersig=" + userSig + "&random=2706793671&contenttype=json";
        JSONObject jsonObject = new JSONObject();
        com.alibaba.fastjson.JSONArray jsonArray = new com.alibaba.fastjson.JSONArray();
        JSONObject jsonObject1 = new JSONObject();
        jsonObject1.put("UserID", "110");
        JSONObject jsonObject2 = new JSONObject();
        jsonObject2.put("UserID", "123456");
        jsonArray.add(jsonObject1);
        jsonArray.add(jsonObject2);
        jsonObject.put("DeleteItem", jsonArray);
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);

        StringEntity params = new StringEntity(jsonObject.toJSONString(), "utf-8");
        params.setContentType("application/json");
        httpPost.setEntity(params);

        try {
            HttpResponse response = httpClient.execute(httpPost);
            String strResult = EntityUtils.toString(response.getEntity(), "utf-8");
            org.json.JSONObject object = new org.json.JSONObject(strResult);
            Integer code = (Integer) object.get("ErrorCode");
            if (code == 0) {
                System.out.println("删除成功");
            } else {
                System.out.println("删除失败");
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}
